package com.net.xpay.partner.secutiry;

import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.net.common.encryption.BlowfishUtil;
import com.net.common.enums.EnumUtil;
import com.net.common.util.NetUtil;
import com.net.common.web.CookieHelper;
import com.net.xpay.common.domain.partner.Partner;
import com.net.xpay.common.enums.user.ClientFrom;
import com.net.xpay.common.enums.user.SecurityStatus;
import com.net.xpay.common.manager.partner.PartnerManager;
import com.net.xpay.core.constant.PartnerWebConstant;
import com.net.xpay.core.constant.PoseidonErrorCode;
import com.net.xpay.core.helper.DomainHelper;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;

/**
 * @author  on 06/03/2018.
 * 处理Session相关的信息:
 * 1. 生成remmberMe的key和从key获取User
 * 2. 验证Session对应的用户是否安全(处理黑名单之类的问题)
 */
@Slf4j
@Component
public class SessionManager {
    private static final Logger LOGGER = LoggerFactory.getLogger(SessionManager.class);

    private static final String REMEMBER_ME_KEY = "xpay-?$123456@";

    private static final String REMEMBER_ME_SPLITTER = "||";

    @Autowired
    private DomainHelper domainHelper;

    @Autowired
    private PartnerManager partnerManager;

    public String getRememberMeKey(Long userId, ClientFrom clientFrom) {
        if (userId == null || clientFrom == null) {
            return null;
        }
        try {
            return BlowfishUtil.encrypt(REMEMBER_ME_KEY, userId + REMEMBER_ME_SPLITTER + clientFrom.getValue());
        } catch (Exception e) {
            LOGGER.warn("encrypt remember me key failed", e);
        }
        return "";
    }

    public AutoLoginToken getAutoLoginTokenFromRememberMe(String rememberMeKey, HttpServletRequest request, HttpServletResponse response) {
        if (Strings.isNullOrEmpty(rememberMeKey)) {
            return null;
        }
        String ip = NetUtil.getRequestRealIp(request);

        String val;
        try {
            val = BlowfishUtil.decrypt(REMEMBER_ME_KEY, rememberMeKey);
        } catch (Exception e) {
            LOGGER.warn("decrypt remember me key failed|ip={}", ip, e);
            return null;
        }
        log.info("val = {}", val);
        List<String> data = Splitter.on(REMEMBER_ME_SPLITTER).omitEmptyStrings().splitToList(val);
        Partner partner = partnerManager.getById(Long.valueOf(data.get(0)));
        ClientFrom clientFrom = EnumUtil.getStringEnum(data.get(1), ClientFrom.class);
        if (partner == null || clientFrom == null) {
            //清除掉跨站的cookie
            String cookieDomain = domainHelper.getCookieDomain(request);
            cookieDomain = cookieDomain.substring(cookieDomain.indexOf(".") + 1);
            CookieHelper.deleteCookie(response, cookieDomain, "/", PartnerWebConstant.REMEMBER_ME_COOKIE_NAME);
            log.info("getAutoLoginTokenFromRememberMe partner null|rememberMeKey={}|val={}|ip={}", rememberMeKey, val, ip);
            return null;
        }
        return new AutoLoginToken(partner, clientFrom);
    }

    public void checkUserSecurity(Partner partner) throws WebInsufficientAuthException {
        if (partner.getSecurityStatus() == SecurityStatus.FROZEN) {
            throw new WebInsufficientAuthException(PoseidonErrorCode.NEED_LOGIN, "请重新登陆");
        }
    }
}
